package demo8

import "fmt"

// 观察者设计模式，也叫做订阅发布模式，一对多的关系，
// 里面用到的切片，可以使用redis或者管道来代替根据场景来变换即可

// 发布者
type Subject struct {
	observers []Observer // 订阅者
	context   string     // 主题
}

func NewSubject() *Subject {
	return &Subject{
		observers: make([]Observer, 0),
	}
}

// 添加订阅者
func (s *Subject) Attach(o Observer) {
	s.observers = append(s.observers, o)
}

// 通知每一个订阅者
func (s *Subject) notify() {
	// 这里可以做通知监听，一旦有新数据则通知出去
	for _, o := range s.observers {
		o.Update(s) // 订阅者方法，获取内容或者其他动作
	}
}

// 订阅的主题 context改变的话 对应的observers也跟着更新
// 联动
func (s *Subject) UpdateContext(context string) {
	s.context = context
	s.notify()
}

type Observer interface {
	Update(*Subject)
}

type Reader struct {
	name string
}

func NewReader(name string) *Reader {
	return &Reader{
		name: name,
	}
}

func (r *Reader) Update(s *Subject) {
	fmt.Printf("%s receive %s\n", r.name, s.context)
}
